﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web.Http;
using BigData.Models;
using BigDataFramework.Repositories;
using BigData.DataContracts.Objects.BigData;
using MongoDB.Bson;
using System.Web;
using System.Text.RegularExpressions;

namespace BigData.Controllers.api
{
    public class TimelineController : ApiController
    {
        private MongoDBRepository dbContext { get; set; }

        public TimelineController()
        {
            dbContext = new MongoDBRepository();
        }

        //
        // GET: api/internal/timeline/{PersonID}?searchterm={searchterm}&startdate={startDate}&endDate={enddate}

        public Timeline Get(string id, string searchterm = "", string startDate = "", string endDate = "")
        {
            List<Event> eventsList;
            DateTime startDateFilter;
            DateTime endDateFilter;
            RegexOptions options;

            // Retrieve affiliated person
            BigDataUser person = dbContext.ReadOne<BigDataUser>(p =>
                        p._id == id
                    &&  p.RecordStartDate < DateTime.Now
                    &&  p.RecordEndDate > DateTime.Now
                );

            string text = "Brought to you by the <i>BigData Project</i>";
            DateTime date = person.RecordStartDate;

            if (string.IsNullOrEmpty(startDate) || !DateTime.TryParse(startDate, out startDateFilter))
                startDateFilter = DateTime.MinValue;

            if (string.IsNullOrEmpty(endDate) || !DateTime.TryParse(endDate, out endDateFilter))
                endDateFilter = DateTime.MaxValue;

            // Specify the kind of input dates
            startDateFilter = DateTime.SpecifyKind(startDateFilter, DateTimeKind.Local);
            endDateFilter = DateTime.SpecifyKind(endDateFilter, DateTimeKind.Local);

            // Retrieve the events for that person
            IQueryable<Event> events = dbContext.Read<Event>(e =>

                       (e.AffiliatedUserIds.Contains(ObjectId.Parse(person._id)))
                    && (startDateFilter <= e.StartDate)
                    && (endDateFilter   >= e.EndDate)

                    // The record must be active
                    && (DateTime.Now    >= e.RecordStartDate)
                    && (DateTime.Now    <= e.RecordEndDate)

                );

            if (!string.IsNullOrEmpty(searchterm))
            {
                options = RegexOptions.IgnoreCase | RegexOptions.IgnorePatternWhitespace | RegexOptions.CultureInvariant;

                events = events.Where(e =>
                            Regex.IsMatch(e.Text, searchterm, options)
                        ||  Regex.IsMatch(e.Headline, searchterm, options)
                    );
            }

            eventsList = events.ToList();

            if (events.Count() > 0 && events.Min(e => e.StartDate) < date)
                date = events.Min(e => e.StartDate);

            // If the start date filter is set to before the user's start date, then set the start date to be that.
            if (startDateFilter < date && startDateFilter != DateTime.MinValue)
                date = startDateFilter;

            return new Timeline(
                    string.Format("{0} {1}'s Timeline", person.FirstName, person.LastName),
                    "default",
                    text,
                    date.ToLocalTime().ToString("yyyy,MM,dd"),
                    (eventsList.Count != 0 ? eventsList : new List<Event>())
                );
        }
    }
}
